/** GW Common.  This file holds various common routines to support GeoWiki.
*/
if( typeof console != 'undefined' ){ console.debug('gwviewedit.js');}

// *****************************************************************************
// Feature support routines
// Do not try to unroll these functions.  Each instance preserves the contents 
// different instances of the feature which are needed later when the event
// triggers.
// *****************************************************************************

// Init map data
GW.initMap = function(){
    // create map features
    for (var f in GW.features){
        feature = GW.features[f];
        switch( feature.ftype ){
            case 'icon':
                feature.feature = GW.createMarker( feature );
                break;
            case 'line':
                feature.feature = GW.createLine( feature );
                break;
            case 'shape':
                feature.feature = GW.createShape( feature );
                break;
        }
        GW.setExtra( feature );
    }
    // attach page's KMLs fixme:
    //for (var k in GW.kmls ){
        //var n = 'http://great-loop.appspot.com/static/kml/' + GW.kmls[k] + '.kml';
        // GW.console( 'kml ' + n )
        //var kml = new GGeoXml( n );
        //if( kml ){
            //GW.pMap._map.addOverlay( kml );
        //}   
    //}
};
// Init feature data table
GW.initFeatureDataTable = function(){
    // Custom icon formatter
    this.iconFormatter = function( elCell, oRecord, oColumn, oData ){
        var ftype = oRecord.getData( 'ftype' );
        var icon = oData;
        var color = oRecord.getData( 'color' );
        switch( ftype ){
            case GW.TYPE_ICON:
                elCell.innerHTML = '<img src="/gw/json/marker/' + icon + '">';
                break;
            case GW.TYPE_POLYLINE:
                elCell.innerHTML = '<img src="/static/img/polyline.png" style="background-color:' + 
                    GW.colors[color] + '; opacity:' + GW.POLY_OPACITY + '; filter:alpha(opacity=' + GW.POLY_OPACITY*100 + ');">';
                break;
            case GW.TYPE_POLYGON:
                elCell.innerHTML = '<img src="/static/img/polygon.png" style="background-color:' + 
                    GW.colors[color] + '; opacity:' + GW.POLY_FILLOPACITY + '; filter:alpha(opacity=' + GW.POLY_FILLOPACITY*100 + ');">';
                break;
        }
    };
    YAHOO.widget.DataTable.Formatter.iconFormatter = this.iconFormatter; 
    // Custom date formatter
    this.dateFormatter = function( elCell, oRecord, oColumn, oData){
        elCell.innerHTML = oData.substr( 0, 16 );
    };
    YAHOO.widget.DataTable.Formatter.dateFormatter = this.dateFormatter; 
    // create feature list
    var colDefs = [
        {key:"icon", label: '', sortable:true, resizeable:true, formatter:"iconFormatter"},
        {key:"name", label: 'Name', sortable:true, resizeable:true},
        {key:"description", label: 'Description', sortable:true, resizeable:true},
        {key:"extra", label: 'Extra', sortable:true, resizeable:true}
    ];
    GW.ds = new YAHOO.util.DataSource(GW.features);
    GW.ds.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
    GW.ds.responseSchema = {
        fields: ["wikiTitle","ftype","icon","color","width", "name", 
            "description", "extra", "tags", "author", "date", "points"]
    };
    GW.dt = new YAHOO.widget.DataTable("idFeatureTable", colDefs, GW.ds, {});
    //GW.dt.subscribe( "rowMouseoverEvent", GW.dt.onEventHighlightRow);
    GW.dt.subscribe( "rowClickEvent", GW.showEditFeature);
    GW.dt.subscribe( "rowMouseoverEvent", GW.dt.onEventHighlightRow);
    GW.dt.subscribe( "rowMouseoutEvent", GW.dt.onEventUnhighlightRow);
    return;
};
// Check if point is on map
GW.pointOnMap = function( p ){
    var m = GW.pMap._map.getBounds();
    var msw = m.getSouthWest();
    var mne = m.getNorthEast();
    // check lat
    var lat = p.lat();
    var lng = p.lng();
    return (lat > msw.lat() && lat < mne.lat() && lng > msw.lng() && lng < mne.lng());
};
// Find feature given row
GW.findFeatureFromRow = function( row ){
    for( var f in GW.features){
        // look for this row
        if (GW.features[f].tr == row ){
            return GW.features[f];
        }
    }
    return null;
};
// Setup a feature for editing
GW.currentEditFeature = null;                                                   // the feature we are currently showing/editing
GW.currentEditRow = null;                                                       // the row we are currently showing/editing
GW.showEditFeature = function( args ){
    GW.editFeature( args.target );
};
GW.editFeature = function( row ){
    // get the row and it's data
    GW.currentEditRow = row;                                                    // remember the row
    var data = GW.dt.getRecord( GW.currentEditRow ).getData();                  // get the data
    GW.currentEditFeature = GW.findFeatureFromRow( GW.currentEditRow );         // find the feature
    // position the map appropriately
    if( GW.currentEditFeature.ftype == GW.TYPE_ICON ){ 
        var point = GW.currentEditFeature.feature.getLatLng();
        if( !GW.pointOnMap( point )) {
            GW.pMap._map.setCenter( point );
        }
    } else { 
        var bounds = GW.currentEditFeature.feature.getBounds();
        var sw = bounds.getSouthWest();
        var ne = bounds.getNorthEast();
        if( !GW.pointOnMap( sw ) | !GW.pointOnMap( ne )){
            var lat = (sw.lat()+ne.lat())/2.0;
            var lng = (sw.lng()+ne.lng())/2.0;
            var x = new GLatLng( lat, lng );
            var zoom = GW.pMap._map.getBoundsZoomLevel( bounds );
            GW.pMap._map.setCenter( x, zoom - 1 );
        }
    }
    var icon = document.getElementById( 'idIconCurrent' );                      // build the required icon
    switch( data.ftype ){
        case GW.TYPE_ICON:
            icon.src = '/gw/json/marker/' + data.icon;
            icon.style.backgroundColor = '';
            icon.style.opacity = 1;
            icon.style.filter = '';
            break;
        case GW.TYPE_POLYLINE:
            icon.src = '/static/img/polyline.png';
            icon.style.backgroundColor = GW.colors[data.color];
            icon.style.opacity = GW.POLY_OPACITY;
            icon.style.filter = 'alpha(opacity=' + GW.POLY_OPACITY*100 + ')';
            break;
        case GW.TYPE_POLYGON:
            icon.src = '/static/img/polygon.png';
            icon.style.backgroundColor = GW.colors[data.color];
            icon.style.opacity = GW.POLY_FILLOPACITY;
            icon.style.filter = 'alpha(opacity=' + GW.POLY_FILLOPACITY*100 + ')';
            break;
    }
    var form = document.getElementById( 'idForm2' );                            // load the form data
    form.name.value = data.name;
    var dsc = data.description;
    dsc = dsc.replace(/(^\s*)|(\s*$)/gi, '' );
    form.description.value = dsc;
    //form.extra.value = data.extra;
    //form.tags.value = data.tags;
    form.author.value = data.author;
    form.date.value = data.date;
    // only display the icon/color divs if we are editing
    if( GW.enableEdit ) {
        // hide the color and icon divs
        var divIcon = document.getElementById( 'idIconTab' );
        divIcon.style.display = 'none';
        var divColor = document.getElementById( 'idColorTab' );
        divColor.style.display = 'none';
        var divXTab = document.getElementById( 'idXTab' );
        divXTab.style.display = 'none';
        // uncover the color or icon div as appropriate
        switch( data.ftype ){
            case GW.TYPE_ICON:
                divIcon.style.display = 'block';
                break;
            case GW.TYPE_POLYLINE:
            case GW.TYPE_POLYGON:
                divColor.style.display = 'block';
                break;
        }
    }
    return;
};
// Setup no feature in the edit form
GW.editFeatureNone = function(){
    var icon = document.getElementById( 'idIconCurrent' );                      // build the required icon
    icon.src = "/static/img/none.png";
    icon.style.backgroundColor = '';
    icon.style.opacity = .4;
    icon.style.filter = '';
    var form = document.getElementById( 'idForm2' );                            // load the form data
    form.name.value = '';
    form.description.value = '';
    //form.extra.value = '';
    //form.tags.value = '';
    form.author.value = '';
    form.date.value = '';
    var divIcon = document.getElementById( 'idIconTab' );                       // hide icon div
    divIcon.style.display = 'none';
    var divColor = document.getElementById( 'idColorTab' );                     // hide color div
    divColor.style.display = 'none';
};
// create a marker feature for the map
GW.createMarker = function( feature ) {
    // set our location
    var cord = feature.points[0];
    var point = new GLatLng( cord[0], cord[1] );
    // create our icon
    var icon = new GIcon( G_DEFAULT_ICON );
    icon.image = "/gw/json/marker/" + feature.icon;
    icon.iconSize = new GSize( 32, 32 );
    icon.shadowSize=new GSize(56,32);
    icon.iconAnchor=new GPoint(16,32);
    icon.infoWindowAnchor=new GPoint(16,0);
    // create marker
    var markerOptions = { icon: icon, draggable: true, autoPan: true,
        title: feature.name };
    var marker = new GMarker(point, markerOptions );
    feature.feature = marker;
    GW.pMap._map.addOverlay( feature.feature );                                 // put it on the map
    // add info window listener
    feature.clickEvent = GEvent.addListener(feature.feature, "click", function() {
        marker.openInfoWindowHtml( feature.description );
    });
    if( ! GW.enableEdit ) {
        marker.disableDragging();
        return marker;
    }
    // Listen for drag and update location if marker is moved
    feature.dragEvent = GEvent.addListener(feature.feature, "dragend", function() {
        feature.changed = true;                                                 // mark the record as changed
        GW.updateExtra( feature );
    });
    return marker;
};
// create a line feature for our map
GW.createLine = function( feature ){
    // default editable
    points = [];
    for ( var i = 0; i < feature.points.length; i++ ){
        points[i] = new GLatLng( feature.points[i][0], feature.points[i][1] );
    }
    var line = new GPolyline( points, feature.color, feature.width, GW.POLY_OPACITY );
    feature.feature = line;
    GW.pMap._map.addOverlay( feature.feature );                                 // put it on the map
    GW.createLineShape( feature );
    return line;
};
// create a shape feature for our map
GW.createShape = function( feature ){
    // default editable
    points = [];
    for ( var i = 0; i < feature.points.length; i++ ){
        points[i] = new GLatLng( feature.points[i][0], feature.points[i][1] );
    }
    var shape = new GPolygon( points, feature.color, feature.width,
        GW.POLY_OPACITY, feature.color, GW.POLY_FILLOPACITY );
    feature.feature = shape;
    GW.pMap._map.addOverlay( feature.feature );                                 // put it on the map
    GW.createLineShape( feature );
    return shape;
};
// new polyline/polygon initialization
GW.createLineShape = function( feature ) {
    if( ! GW.enableEdit ) return;
    // enable drawing and editing
    feature.feature.enableEditing({onEvent: "mouseover"});
    feature.feature.disableEditing({onEvent: "mouseout"});
    feature.lineupdatedEvent = GEvent.bind(feature.feature, "lineupdated", feature, function() {
        feature.changed = true;                                                 // mark the record as changed
        GW.updateExtra( feature );
        return;
    });
    feature.clickEvent = GEvent.addListener(feature.feature, "click", function(latlng, index) {
        if (typeof index == "number") {
            feature.feature.deleteVertex(index);
        }
    });
};
GW.updateExtra = function( feature ){
    // This is called when a feature is edited in the map panel
    GW.setExtra( feature );                                                     // set the value
    var data = GW.dt.getRecord( feature.tr ).getData();                         // existing data
    data.extra = feature.extra;                                                 // set new extra value
    GW.dt.updateRow( feature.tr, data );                                        // refresh the dataTable
    return;
};
// compute feature extra
GW.setExtra = function( feature ){
    switch( feature.ftype ){
        case GW.TYPE_ICON:
            var latlng = feature.feature.getPoint();
            feature.extra = "(" + Math.round(latlng.y * 10000) / 10000 + ", " + Math.round(latlng.x * 10000) / 10000 + ")";
            break;
        case GW.TYPE_POLYLINE:
            var val = feature.feature.getLength();
            feature.extra = (Math.round(val / 10) / 100) + "km<br />" + 
                (Math.round(val*0.0621371192)/100) + 'mi';
            break;
        case GW.TYPE_POLYGON:
            var area = feature.feature.getArea();
            feature.extra = (Math.round(area / 10000) / 100) + "km<sup>2</sup><br />" +
                (Math.round(0.386102159*area/10000)/ 100) + "mi<sup>2</sub>";
            break;
        }
};
// Connect the features json array to the DT
GW.connectFeaturesToDT = function(){
    // GW.dt holds the datatable
    // features holds the json array of geo features
    // need to connect features to the DT row instance so that we can update
    // extra when the feature is edited on the map
    // use getFirstTrEl and getNextTrEl to iterate over the DT rows and set in
    // the features table
    var tr = GW.dt.getFirstTrEl();
    var findex = 0;
    while( tr ){
        GW.features[findex].tr = tr;                                            // link GW.features back to the proper GW.dt row
        findex += 1;
        tr = GW.dt.getNextTrEl(tr);
    }
    return;
};
// set feature changed value
GW.setFeatureChanged = function(){
    // GW.features holds the features.  We set changed to false so when a
    // feature is edited we know.
    for( var i in GW.features ){
        var f = GW.features[i];
        f.changed = false;
        f.deleted = false;
    }
    return;
};


if( typeof console != 'undefined' ){ console.debug('gwviewedit.js loaded'); }

